package com.ustb.springboot.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ustb.springboot.common.utils.JwtUtil;
import com.ustb.springboot.common.utils.R;
import com.ustb.springboot.common.utils.SecretUtil;
import com.ustb.springboot.common.utils.TokenUtil;
import com.ustb.springboot.controller.dto.UserDto;
import com.ustb.springboot.dao.*;
import com.ustb.springboot.entity.*;
import com.ustb.springboot.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Stream;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    @Resource
    private UserDao userDao;

    @Resource
    private UserRoleDao userRoleDao;

    @Resource
    private RoleDao roleDao;
    @Resource
    private RolePermissionDao rolePermissionDao;

    @Resource
    private PermissionDao permissionDao;

    @Resource
    private UserDeptDao userDeptDao;

    @Resource
    private DeptDao deptDao;

    //注册方法
    @Override
    public R register(UserEntity userEntity) {
        //判断用户是否存在 存在返回false 重新选择用户名
        //前端检测空值
        if (null == userEntity.getUsername() || null == userEntity.getPassword())
            return R.error(2000, "用户名或密码为空值");

        //查询语句初始化
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userEntity.getUsername());

        if (!userDao.exists(queryWrapper)) {
            //获取加密数据  加密后传回map包含password和salt
            Map<String, String> hashMap = SecretUtil.Encryption(userEntity.getPassword());
            //set用户密码和盐值
            userEntity.setPassword(hashMap.get("password")).setSalt(hashMap.get("salt"));
            //存入数据库
            userDao.insert(userEntity);
            return R.ok(20000, "注册成功！");
        } else return R.error(2000, "用户名已存在");
    }

    //登录方法
    @Override
    public R login(UserDto userDto) {
        //null检测
        if (null == userDto || null == userDto.getUsername() || null == userDto.getPassword())
            return R.error(2000, "用户名或密码为空值");
        //根据传入dto对象 在数据库根据用户名查询密码(加密后)
        //与传入dto对象的密码进行比较
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userDto.getUsername());
        UserEntity userEntity = userDao.selectOne(queryWrapper);

        if (null == userEntity)
            return R.error(2000, "用户不存在");//query结果为null

        //调用SecretUtil校验  校验通过生成并返回token 放行拦截器
        if (SecretUtil.checkEncryption(userDto.getPassword(), userEntity.getSalt(), userEntity.getPassword())) {
            Integer id = userEntity.getId();
            HashMap<String, String> payload = new HashMap<>();
            payload.put("id", id.toString());
            payload.put("username", userDto.getUsername());
            String token = JwtUtil.getJWToken(payload);
            return R.ok(20000, "登录成功").put("token", token);
        } else return R.error(2000, "密码错误");//密码不匹配

    }

    @Override
    public R getInfo(HttpServletRequest request) {
        //用户id
        Integer userId = TokenUtil.getId(request);
        //返回用户信息
        //用户名username  头像avatar  角色role[]  权限permissions[] (部门dept )

        //获取角色信息
        //根据用户id查询UserRole表 获取RoleId
        List<UserRoleEntity> userRoleEntities = userRoleDao.selectList(new QueryWrapper<UserRoleEntity>().eq("user_id", userId));
        List<RoleEntity> roles = new LinkedList<>();
        List<Integer> roleIdList = new LinkedList<>();
        for (UserRoleEntity userRole : userRoleEntities) {
            roleIdList.add(userRole.getRoleId());
            roles.add(roleDao.selectById(userRole.getRoleId()));
        }

        //获取权限
        //根据roleId 查询 rolePermission表 获取permissionId List
        List<RolePermissionEntity> rolePermissionList = new LinkedList<>();
        for (Integer roleId : roleIdList) {
            List<RolePermissionEntity> rolePermissionEntityList = rolePermissionDao.selectList(new QueryWrapper<RolePermissionEntity>().eq("role_id", roleId));

            rolePermissionList.addAll(rolePermissionEntityList);
        }
        Set<PermissionEntity> permissions = new HashSet<>();
        for (RolePermissionEntity rolePermissionEntity : rolePermissionList) {
            permissions.add(permissionDao.selectById(rolePermissionEntity.getPermissionId()));
        }
        //排序
        Stream<PermissionEntity> sortedPermissions = permissions.stream().sorted(Comparator.comparing(PermissionEntity::getId));

        //获取部门信息
        List<UserDeptEntity> userDeptEntities = userDeptDao.selectList(new QueryWrapper<UserDeptEntity>().eq("user_id", userId));
        List<DeptEntity> depts = new LinkedList<>();
        for (UserDeptEntity userDeptEntity : userDeptEntities) {
            depts.add(deptDao.selectById(userDeptEntity.getDeptId()));
        }
        //ToDo 头像url
        String imgUrl = "https://www.ustb.edu.cn/images/content/2017-04/20170418142450153379.png";

        //返回内容
        HashMap<String, Object> res = new HashMap<>();
        res.put("name", TokenUtil.getName(request));
        res.put("avatar", imgUrl);
        res.put("roles", roles);
        res.put("permissions", sortedPermissions);
        res.put("depts", depts);
        return R.ok(20000, "获取信息成功").put("data", res);
    }

    @Override
    public String queryUserNameWithUserId(String UserId) {
        QueryWrapper<UserEntity> userEntityQueryWrapper = new QueryWrapper<>();
        userEntityQueryWrapper.eq("id",UserId);
        List<UserEntity> userEntities = userDao.selectList(userEntityQueryWrapper);
        if(null != userEntities)
            return userEntities.get(0).getUsername().toString();
        else
            return null;
    }

    @Override
    public String queryNickNameWithUserId(String UserId) {
        QueryWrapper<UserEntity> userEntityQueryWrapper = new QueryWrapper<>();
        userEntityQueryWrapper.eq("id",UserId);
        List<UserEntity> userEntities = userDao.selectList(userEntityQueryWrapper);
        if(null != userEntities)
            return userEntities.get(0).getUsername().toString();
        else
            return null;
            }
}
